package com.xiaoyy.core.config.util;

import cn.hutool.crypto.SecureUtil;
import com.xiaoyy.core.common.cache.CacheConst;
import com.xiaoyy.core.common.enums.EquipmentTypeEnum;
import com.xiaoyy.core.common.enums.ErrorEnum;
import com.xiaoyy.core.common.exception.AppException;
import com.xiaoyy.core.common.vo.SessionInfo;
import com.xiaoyy.core.common.vo.TokenVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Set;

/**
 * 登录工具类
 * */
@Service
public class TokenLoginHelper {
    @Autowired
    RedisUtil redisUtil;
    @Value("${system.config.token.timeout}")
    private Long timeout;
    @Value("${system.config.token.app.timeout}")
    private Long appTimeout;
    @Value("${system.config.token.refresh.timeout}")
    private Long refreshTimeout;
    /**
     * 登录
     * */
    public TokenVO login( SessionInfo sessionInfo){
        String accessToken = makeToken(sessionInfo);
        TokenVO tokenVO = new TokenVO();
        tokenVO.setAccessToken(accessToken);
        String redisKey= CacheConst.ACCESS_TOKEN+":"+accessToken;
        sessionInfo.setExpireFreshTime(System.currentTimeMillis());
        tokenVO.setExpireFreshTime(System.currentTimeMillis());
        String userKey =SecureUtil.md5(sessionInfo.getUserId() + ":" + sessionInfo.getLoginType()+ ":" + sessionInfo.getEquipmentType()+ ":" + sessionInfo.getUserType());
        String userTokenKey = CacheConst.USER_LOGIN_TOKEN;
        if (redisUtil.hHasKey(userTokenKey,userKey)){
            String oldToken = (String) redisUtil.hget(userTokenKey,userKey);
            redisUtil.del(CacheConst.ACCESS_TOKEN+":"+oldToken);
        }
        if (EquipmentTypeEnum.PC.getType().equals(sessionInfo.getEquipmentType())) {
            sessionInfo.setExpireMinute(timeout);
            tokenVO.setExpireMinute(timeout);
            redisUtil.set(redisKey, sessionInfo,timeout);
            redisUtil.hset(userTokenKey, userKey, accessToken, timeout);
        }else{
            sessionInfo.setExpireMinute(appTimeout);
            tokenVO.setExpireMinute(appTimeout);
            redisUtil.set(redisKey, sessionInfo,appTimeout);
            redisUtil.hset(userTokenKey, userKey, accessToken, appTimeout);
        }
        return tokenVO;
    }

    public String makeToken(SessionInfo sessionInfo){
        Long sysTime=System.currentTimeMillis();
        return SecureUtil.md5(sessionInfo.getUserId()+":"+sessionInfo.getUserType()+":"+sessionInfo.getEquipmentType()+":"+sessionInfo.getLoginType()+":"+sysTime);
    }

    /**
     * 退出
     * */
    public void logout(String accessToken) {
        if (StringUtils.isBlank(accessToken)){
            return;
        }
        String redisKey= CacheConst.ACCESS_TOKEN+":"+accessToken;
        if (redisUtil.hasKey(redisKey)){
            SessionInfo sessionInfo = (SessionInfo) redisUtil.get(redisKey);
            String userKey =SecureUtil.md5(sessionInfo.getUserId() + ":" + sessionInfo.getLoginType()+ ":" + sessionInfo.getEquipmentType()+ ":" + sessionInfo.getUserType());
            String userTokenKey = CacheConst.USER_LOGIN_TOKEN;
            if (redisUtil.hHasKey(userTokenKey,userKey)){
                redisUtil.hdel(userTokenKey,userKey);
            }
            redisUtil.del(redisKey);
        }
    }
    /**
     * 校验token是否存在或过期
     * */
    public boolean checkToken(String accessToken) {
        if (StringUtils.isBlank(accessToken)){
            return false;
        }
        SessionInfo sessionInfo = getSessionInfo(accessToken);
        if (sessionInfo==null){
            return false;
        }
        if (System.currentTimeMillis()-sessionInfo.getExpireFreshTime()>sessionInfo.getExpireMinute()){
            return false;
        }
        return true;
    }
    /**
     * 获取用户信息,重新更新缓存过期时间
     * */
    public SessionInfo getSessionInfo(String accessToken) {
        if (StringUtils.isBlank(accessToken)){
            return null;
        }
        String redisKey= CacheConst.ACCESS_TOKEN+":"+accessToken;
        if (redisUtil.hasKey(redisKey)){
            SessionInfo  sessionInfo = (SessionInfo) redisUtil.get(redisKey);
            String userKey =SecureUtil.md5(sessionInfo.getUserId() + ":" + sessionInfo.getLoginType()+ ":" + sessionInfo.getEquipmentType()+ ":" + sessionInfo.getUserType());
            String userTokenKey = CacheConst.USER_LOGIN_TOKEN;
            sessionInfo.setExpireFreshTime(System.currentTimeMillis());
            if (EquipmentTypeEnum.PC.getType().equals(sessionInfo.getEquipmentType())) {
                sessionInfo.setExpireMinute(timeout);
                redisUtil.set(redisKey, sessionInfo,timeout);
                redisUtil.hset(userTokenKey, userKey, accessToken, timeout);
            }else{
                sessionInfo.setExpireMinute(appTimeout);
                redisUtil.set(redisKey, sessionInfo,appTimeout);
                redisUtil.hset(userTokenKey, userKey, accessToken, appTimeout);
            }
            return sessionInfo;
        }
        return null;
    }

}
